home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-14 | 18.6 KB | 693 lines | [TEXT/MPS ] |
- /* _________________________________________________________________________________________________________ //
- Copyright © 1992-93 Apple Computer, Inc. All rights reserved.
- Macintosh Developer Technical Support.C++ Macintosh Toolbox Framework.
- Date: 11/6/92
- Revision comments are at the end of this file.
- ---
- TApplication is an abstract base class, TBKApplication is a background only application class,
- TGUIApplication is a window-based user application class. TQTApplication is a QuickTime aware application
- class, TGXApplication is a Quick GX aware application class. Finally TQTAndGXApplication
- handles both QX and QT application work.
- Application.cp contains the needed member functions for the classes defined above.
- _________________________________________________________________________________________________________ */
-
- // INCLUDE FILES
- #ifndef _APPLICATION_
- #include "Application.h"
- #endif
-
-
- // GLOBAL DATA AND FUNCTIONS
- TApplication* gApplication; // universal ptr to the framework
-
- const short kDefaultNumMasters = 8; // number of master pointers
- const OSType kAEResource = 'aedt'; // our AE binding resource
-
- pascal OSErr AEDispatcher(AppleEvent* in,
- AppleEvent* out,
- long Command); // AE Dispatcher
-
-
- // Global Functions
- pascal OSErr AEDispatcher(AppleEvent* in,
- AppleEvent* out,
- long Command)
- {
- gApplication->DispatchAppleEvents(in, out, Command);// dispatch event back to the framework
-
- return noErr;
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TApplication class member function implementations.
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TApplication::TApplication()
- // Default constructor -- put together the basic environment (non-UI model).
- {
- gApplication = this; // hook ptr to the global pointer
-
- // Default base class constructor, define fields to known initial values.
- this->SetState(TApplication::kInit); // set out first state
- fSleepRegion = ::NewRgn(); // define default sleep region for WaitNextEvent (NULL)
- fSleepValue = TApplication::kBackgroundSleepValue;// default sleep value (ticks)
- fEventMask = everyEvent; // default setting
- fMoreMasters = kDefaultNumMasters; // amount of more master calls
-
- this->InitializeMemory(); // initialize memory
- this->InstallAEHandler(); // install our AE handler
- }
-
-
- #pragma segment Application
- TApplication::~TApplication()
- // Default destructor -- empty for the time being.
- {
- }
-
-
- #pragma segment Application
- void TApplication::DoNextEvent()
- // Handle incoming events
- {
- if (!::WaitNextEvent(fEventMask, &fEventRecord, fSleepValue, fSleepRegion))
- fEventRecord.what = nullEvent; // security issue
- }
-
-
- #pragma segment Application
- void TApplication::DoHighLevelEvent()
- // Handle high level events.
- {
- fError = ::AEProcessAppleEvent(&fEventRecord);// handle primarly AEs
- VASSERT(fError == noErr, ("Problems with AEProcessAppleEvent", fError));
- }
-
- #pragma segment Application
- void TApplication::Start()
- // Start the application and let it run until we change the state to Quit.
- {
- this->SetState(TApplication::kRun); // set TApplication to run state
-
- while (fState != TApplication::kQuit)
- this->DoEventLoop();
- this->Quit(); // out from the state, we will quit
- }
-
-
- #pragma segment Application
- void TApplication::Quit()
- // Quit the application, do any possible cleanup.
- {
- }
-
-
- // CORE AE HANDLER METHODS
- #pragma segment Application
- void TApplication::InstallAEHandler()
- // Install our core Apple Event Handler that will dispatch the AEs back to the framework.
- {
- Handle aedtResource = NULL;
- SignedByte state;
- Size tableSize;
- AEEventTablePtr tablePtr;
-
- short numEntries = ::Count1Resources(kAEResource);// find out how many entries in the table
- fError = ResError();
- VASSERT(fError == noErr, ("Problems with Count1Resources = %d", fError));
-
- if(numEntries != 0) // we had 'aedt' resources
- {
- for (short i = 1; i <= numEntries; ++i) // loop through the resources
- {
- aedtResource = ::Get1IndResource('aedt', i);// get resource
- fError = ResError();
- VASSERT(fError == noErr, ("Problems with Get1IndResource = %d", fError));
-
- state = ::HGetState(aedtResource); // get the flags from the handle
- ::HLockHi(aedtResource); // and lock the handle high in memory
-
- tableSize = GetHandleSize(aedtResource);// get the size of the resource
- fError = MemError();
- VASSERT(fError == noErr, ("Problems with GetHandleSize = %d", fError));
-
- short elements = (short)(tableSize / sizeof(AEEventTable));// get N of elements in resource
- tablePtr = (AEEventTablePtr) * aedtResource;// get ptr to the element
-
- // ••• Add the information into our fCommandTable as well for future lookups
- for (short j = 0; j < elements; j++) // go through the elements
- {
- fError = ::AEInstallEventHandler(tablePtr->theClass, tablePtr->theID, (EventHandlerProcPtr)AEDispatcher, tablePtr->theValue, false);
- VASSERT(fError == noErr, ("Problems with AEInstallEventHandler = %d", fError));
- ++tablePtr;
- }
- ::HSetState(aedtResource, state); // restore state
- ::ReleaseResource(aedtResource); // release the resource
- }
- }
- }
-
-
- #pragma segment Application
- void TApplication::DispatchAppleEvents(AppleEvent* in,
- AppleEvent* out,
- long command)
- // Dispatch to the right Handler based on the command in the AE (refCon).
- {
- switch (command)
- {
- case cQuitCommand: // a quit AE
- this->HandleQuit(in, out, command);
- break;
- case cNewCommand: // a new AE
- this->HandleOpen(in, out, command);
- break;
- case cOpenCommand: // an open document AE
- this->HandleOpenDocuments(in, out, command);
- break;
- case cPrintCommand: // a print AE
- this->HandlePrint(in, out, command);
- break;
- default: // hmm, something else then…
- ASSERT(false, "\pProblem: We are dealing with an AE command that we have no handler for");
- break;
- }
- }
-
-
- #pragma segment Application
- OSErr TApplication::HandleQuit(AppleEvent* /*in*/,
- AppleEvent* /*out*/,
- long /*refCon*/)
- // Our General Quit Handler. Set state to Quit and return.
- {
- this->SetState(TApplication::kQuit); // set state to Quit
- return noErr; // need to have this due to AEHandler prototype
- }
-
-
- #pragma segment Application
- OSErr TApplication::HandleOpen(AppleEvent* /*in*/,
- AppleEvent* /*out*/,
- long /*refCon*/)
- {
- return errAEEventNotHandled; // need to have this due to AEHandler prototype
- }
-
- #pragma segment Application
- OSErr TApplication::HandleOpenDocuments(AppleEvent*/*in*/ ,
- AppleEvent*/*out*/ ,
- long /*refCon*/)
- {
- return errAEEventNotHandled; // need to have this due to AEHandler prototype
- }
-
- #pragma segment Application
- OSErr TApplication::HandlePrint(AppleEvent* /*in*/,
- AppleEvent* /*out*/,
- long /*refCon*/)
- {
- return errAEEventNotHandled; // need to have this due to AEHandler prototype
- }
-
-
- // STATE CHANGE METHODS
- #pragma segment Application
- void TApplication::SetState(TApplication::EState theState)
- {
- fState = theState;
- }
-
-
- // MAIN INTERFACE
- #pragma segment Application
- void TApplication::InitializeMemory()
- // Initialize issues dealing with memory use.
- {
- ::MaxApplZone(); // increase the zone
- for (short i = 0; i < fMoreMasters; i++) // bounce up the amount of master pointers
- ::MoreMasters();
- fError = MemError();
- VASSERT(fError == noErr, ("Problems with MoreMasters = %d", fError));
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TBKApplication class member function implementations
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TBKApplication::TBKApplication()
- {
- }
-
-
- #pragma segment Application
- TBKApplication::~TBKApplication()
- {
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TGUIApplication class member function implementations
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TGUIApplication::TGUIApplication()
- // Initialize the UI toolbox side.
- {
- this->InitializeToolbox(); // Initialize toolbox
- TMenubar myMenubar; // handle my menu bar initialization
-
- fCursHandle = ::GetCursor(watchCursor); // get the watch cursor resource
- ::SetCursor(*fCursHandle); // change the cursor to the watch one
- }
-
-
- #pragma segment Application
- TGUIApplication::~TGUIApplication()
- // Default destructor -- empty for the time being.
- {
- }
-
-
- #pragma segment Application
- void TGUIApplication::InitializeToolbox()
- // Initialize the toolbox requirements for a standard window based application.
- {
- ::InitGraf(&qd.thePort);
- ::InitFonts();
- ::InitWindows();
-
- // _DON'T_ flush disk-inserted or os events or you'll be sorry!
- ::FlushEvents(everyEvent - diskMask - osMask, 0);
-
- // The following toolbox init calls are slightly overhead, but that's fine
- ::InitMenus();
- ::TEInit();
- ::InitDialogs((ResumeProcPtr)NULL);
-
- ::InitCursor();
- }
-
- // MAIN INTERFACE
- #pragma segment Application
- void TGUIApplication::Start()
- // Start the event loop handling.
- {
- ::SetCursor(&qd.arrow); // OK, scursor back to to the arrow one
- TApplication::Start(); // call the inherited Start
- }
-
-
- // EVENT HANDLING MEMBER FUNCTIONS
- #pragma segment Application
- void TGUIApplication::DoEventLoop()
- // This is the big event loop swith statement function.
- {
- this->DoNextEvent(); // get the next event record
-
- // This is the big switch statement, switch on events received
- switch (fEventRecord.what)
- {
- case nullEvent: // we got a periodic null event
- this->DoIdle(); // call idle handler
- break;
-
- case updateEvt: // we got an update event
- this->DoWindowUpdate(); // call the window update member function
- break;
-
- case diskEvt: // we got a disk insertion event (most likely formatting)
- this->DoDiskEvent();
- break;
-
- case mouseDown: // we got a mouse down event
- // get the window where the mouse down happened, and do an action based on this
- switch (::FindWindow(fEventRecord.where, &fCurrentWindow))
- {
- case inSysWindow: // It's a DA window, provide time for that.
- this->DoSystemTime();
- break;
-
- case inDrag: // Move the window to a specific target.
- this->DoDragWindow();
- break;
-
- case inGoAway: // Close the window.
- this->DoGoAwayWindow(); // do window close events
- // ••• Future, Send a Close command
- break;
-
- case inContent: // handle click inside the window
- this->DoInWindowContent();
- break;
-
- case inMenuBar: // handle menu bar clicks
- this->DoMenuCommand();
- break;
-
- default: // ignore any other sane events for the time being
- break;
- }
-
- case app4Evt: // we got a Multifinder event
- switch ((unsigned long)fEventRecord.message >> TApplication::kHighByte)
- {
- case TApplication::kSuspendResumeMessage:// suspend or deactivate message
- if ((fEventRecord.message & TApplication::kResumeMask) == 0)
- fSleepValue = TApplication::kBackgroundSleepValue;
- else // resume or activate message
- fSleepValue = TApplication::kForgroundSleepValue;
- break;
- }
- break;
-
- case kHighLevelEvent:
- this->DoHighLevelEvent(); // handle our high level events (as AEs)
- break;
-
- default:
- break;
- }
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoIdle()
- // Handle idle time
- {
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoSystemTime()
- // Handle DAs
- {
- ::SystemClick(&fEventRecord, fCurrentWindow);
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoDiskEvent()
- // Handle disk events (formatting, floppies inserted and so on).
- {
- Point dlogPoint;
- const short kDILeft = 40;
- const short kDITop = 40;
-
- if (HiWrd(fEventRecord.message) != noErr) // if no error indication
- {
- ::SetPt(&dlogPoint, kDILeft, kDITop); // define the dlog box rect
- fError = ::DIBadMount(dlogPoint, fEventRecord.message);// turn it over to the system
- VASSERT(fError == noErr, ("Problems with DIBadMount = %d ", fError));
- }
- }
-
-
- #pragma segment Application
- void TGUIApplication::DispatchAppleEvents(AppleEvent* in, AppleEvent* out, long command)
- // Take care of the GUI related Apple Events, and dispatch the rest to the TApplication level
- {
- switch(command)
- {
- case cAboutCommand: // Send an AE telling the system to display the About box
- this->DoAboutBox();
- break;
- default:
- TApplication::DispatchAppleEvents(in, out, command);
- break;
- }
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoWindowUpdate()
- // Handle window update events.
- {
- ::BeginUpdate((WindowPtr)fEventRecord.message);
- ::SetPort((WindowPtr)fEventRecord.message); // set port to the right grafport
- this->Draw(); // call the window drawing part
- ::EndUpdate((WindowPtr)fEventRecord.message);
- }
-
-
-
- #pragma segment Application
- void TGUIApplication::DoDragWindow()
- // Handle the inDrag event.
- {
- ::DragWindow(fCurrentWindow, fEventRecord.where, &qd.screenBits.bounds);
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoGoAwayWindow()
- // Handle dogoAway events.
- {
- ::TrackGoAway(fCurrentWindow, fEventRecord.where);
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoInWindowContent()
- // Handle inWindow events.
- {
- if (fCurrentWindow != ::FrontWindow())
- ::SelectWindow(fCurrentWindow); // make the window the foremost one
- else
- this->DoClick(); // handle the click inside the foremost window
- }
-
-
-
- // MENU EVENTS
- #pragma segment Application
- void TGUIApplication::DoMenuCommand()
- // Handle menu mouse events.
- {
- long aCommandNumber;
-
- this->AdjustUserInterface(); // first, make sure the menu entries are enabled/disabled
-
- fMenuResult = ::MenuSelect(fEventRecord.where);// get the selected menu (longword)
-
- aCommandNumber = this->CalculateMenuCommand(fMenuResult); // calculate our command number
-
- // We will handle the most typical menu entries here (Apple, Edit, File)
- // and call DoCommand() with the rest of the possible commands.
-
- this->DoInternalMenus(aCommandNumber); // handle internal menus (Apple)
- this->DoCommand(aCommandNumber); // handle external commands/menus
-
- ::HiliteMenu(0); // unhighlight what MenuSelect hilited and return
- }
-
-
- #pragma segment Application
- long TGUIApplication::CalculateMenuCommand(long menuEntry)
- // Calculate the command number based on the algorithm where the menu entry
- // is either a two-digit or a three-digit number, and where the first number
- // is the menu number.
- {
- long command;
- if (LoWrd(menuEntry) > 9) // use algorithm 2
- {
- command = (HiWrd(menuEntry) * 100) + LoWrd(menuEntry);
- }
- else // use algorithm 1
- command = (HiWrd(menuEntry) * 10) + LoWrd(menuEntry);
-
- return command;
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoInternalMenus(long command)
- // Handle our internal menus, Apple, DAs and so on.
- {
- Str255 daName; // our DA name
- short daRefNum; // our DA refnum
-
- switch (command)
- {
- case cAboutCommand: // our About box?
- fMessenger.Send(kCoreEventClass, kAEAbout);
- break;
-
- default:
- if( HiWrd(fMenuResult) == mApple) // we have a DA?
- {
- ::GetItem(GetMHandle(mApple), (short)LoWrd(fMenuResult), daName);
- daRefNum = ::OpenDeskAcc(daName);
- }
- break;
- }
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoCommand(long command)
- // Handle the default framework menus, post AE commands.
- {
- switch(command)
- {
- case cQuitCommand:
- fMessenger.Send(kCoreEventClass, kAEQuitApplication);
- break;
-
- default:
- TApplication::DoCommand(command); // let the underlying framework take a short
- break;
- }
- }
-
-
- // AE HANDLING OVERRIDES
- #pragma segment Application
- OSErr TGUIApplication::HandleOpen(AppleEvent* /*in*/,
- AppleEvent* /*out*/,
- long /*refCon*/)
- {
- this->DoCreateDocument(); // Default behavior -- open one window ('document').
- return noErr; // need to have this due to AEHandler prototype
- }
-
-
- // DOCUMENT CREATION MEMBER FUNCTIONS
- #pragma segment Application
- void TGUIApplication::DoCreateDocument()
- // Create initially one window.
- {
- TWindow * aWindow = new TWindow;
- ASSERT(aWindow != NULL, "\pWe didn't create a TWindow");
-
- if(aWindow != NULL)
- this->AddDocument(aWindow);
- }
-
-
- #pragma segment Application
- void TGUIApplication::AddDocument(TWindow* theDocument)
- // Add the document (Window) to an internal list of documents.
- {
- fDocument = theDocument;
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoCreateDocument(short windowID)
- // Create initially one window.
- {
- TWindow * aWindow = new TWindow(windowID);
- ASSERT(aWindow != NULL, "\pWe didn't create a TWindow");
-
- if(aWindow != NULL)
- this->AddDocument(aWindow);
- }
-
-
- #pragma segment Application
- void TGUIApplication::Draw()
- // Define drawing instructions inside this method. Default dispatch
- // and draw the currently active document (window).
- {
- fDocument->Draw();
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoClick()
- // Handle a click inside a window, empty for the moment (need to override this one)
- {
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoAboutBox()
- // Present our default about box, override for a better one!
- {
- ASSERT(false, "\pThis is the Gamura framework! Override for a better about box");
- }
-
-
- #pragma segment Application
- void TGUIApplication::DoHelp()
- // This is the hook for a possible help system (something outside the help balloons)
- {
- ASSERT(false, "\pYou triggered the help system, override for a real one!");
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TQTApplication class member function implementations
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TQTApplication::TQTApplication()
- // Initialize the QT specific parts.
- {
- }
-
-
- #pragma segment Application
- TQTApplication::~TQTApplication()
- // Do any possible epilogue cleanup.
- {
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TGXApplication class member function implementations
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TGXApplication::TGXApplication()
- // Initialize the GX specific parts
- {
- }
-
-
- #pragma segment Application
- TGXApplication::~TGXApplication()
- // Do any possible epilogue cleanup.
- {
- }
-
-
- // _________________________________________________________________________________________________________ //
- // TQTAndGXApplication class member function implementations
-
- // CONSTRUCTORS & DESTRUCTORS
-
- #pragma segment Application
- TQTAndGXApplication::TQTAndGXApplication()
- // Initialize the QT and GX specific parts.
- {
- }
-
-
- #pragma segment Application
- TQTAndGXApplication::~TQTAndGXApplication()
- // Do any possible epilogue cleanup.
- {
- }
-
-
- // _________________________________________________________________________________________________________ //
-
-
- /* Change History (most recent last):
- No Init. Date Comment
- 1 khs 11/6/92 New file
- 2 khs 1/14/93 Cleanup
- */
-
-